Profile picture

[k8s] 데이터 영속적으로 관리하는 방법 - Persistent Volume / Persistent Volume Claim

JaehyoJJAng2023년 04월 24일

개요

웹 서비스와 데이터베이스(DB)를 각각의 Pod로 운영하는 경우, 데이터의 영속성이 매우 중요하다는거 다들 아실텐데요!

만약 DB Pod가 종료되거나 재시작되면, Pod 내부 스토리지에 저장된 데이터가 함께 소실되기 때문에

이를 해결하기 위해 Persistent Volume(PV)Persistent Volume Claim(PVC) 을 사용합니다!


이번 글에서는 홈서버 환경과 같은 소규모 클러스터에서의 효율적인 영속 데이터 관리 방법과 PV/PVC의 개념, 그리고 운영 방법에 대해서 간력하게 기록해볼게요!


영속적인 데이터 관리가 필요한 이유?

쿠버네티스에서는 컨테이너가 기본적으로 일시적(temporary) 인 특성을 가지기 때문에,

컨테이너에 저장된 데이터는 해당 컨테이너가 사라지면 같이 삭제됩니다.


개요 챕터에서도 말했듯이, 웹 서비스의 DB Pod가 재시작되면, Pod 내부에 저장된 데이터는 모두 사라지게 됩니다.

따라서 서비스를 운영하는 동안 데이터의 안전한 보존과 복구를 위해 외부 스토리지나 클러스터 외부에 데이터를 따로 보관할 필요가 있게 되는거죠!


PV와 PVC의 이해

Persistent Volume

PV는 클러스터 내에서 관리되는 외부 스토리지 리소스예요!


역할

PV는 클러스터 관리자가 관리하며, 스토리지 제공자(NFS, iSCSI, Ceph, 클라우드 스토리지)에 의해 실제 데이터가 저장됩니다.

즉, Pod가 삭제되거나 재시작되어도 데이터를 유지할 수 있도록 외부에 데이터를 저장하는 역할을 하는거죠!


특징

클러스터 수준에서 제공되며, 다양한 스토리지 백엔드를 지원하고 있어요.

뿐만 아니라 스토리지 용량, 접근 모드(ReadWriteOnce, ReadOnlyMany, ReadWriteMany) 등을 정의할 수도 있죠.


Persistent Volume Claim

PVC는 Pod가 스토리지 리소스를 요청할 때 사용하는 선언적 리소스예요!


역할

개발자가 필요한 스토리지 용량과 접근 모드를 명시하여 PVC를 생성하면,

쿠버네티스는 적절한 PV를 매핑하여 Pod에 제공해주게 됩니다!

이를 통해 Pod는 실제 스토리지의 위치나 세부 구현 방식에 대해 신경 쓸 필요가 없이 데이터만을 저장할 수 있게 되는거죠!


특징

사용자(개발자)는 스토리지의 세부 구현에 대해 알 필요 없이, 단순히 필요한 용량과 성능 요구 사항을 PVC에 명시해주면 돼요!

그럼 PVC는 바인딩(Bound) 상태가 되어 선택된 PV와 연결됩니다!


홈서버에서 영속적 데이터 관리를 위한 방법

소규모 사무실 또는 홈서버에서 쿠버네티스를 운영할 때는 비용과 복잡성을 상당히 신중하게 고려해야 해요.


애초에 기대 트래픽이 그리 높지 않게 측정 된다면 러닝 커브가 있는 쿠버네티스보단 도커 스웜으로 전환하는게 오히려 더 효율적일 수도 있죠.


그리고 비용 부담이 있는 우리로써는 외부 클라우드 스토리지(AWS EBS ..)를 사용하는게 선뜻 내키지가 않죠..


그렇다면 어떤 방법을 사용하는게 제일 효율적일까요?

한번 살펴봅시다!


외부 클라우드 스토리지

외부 클라우드 스토리지는 관리 용이성과 고가용성을 제공하지만,

비용과 네트워크 지연 문제로 홈서버에서는 적합하지 않을 수 있어요!

따라서 여기서는 제외하고 내부 솔루션에 집중하겠습니다~


로컬 스토리지

로컬 스토리지는?:

쿠버네티스 노드의 로컬 디스크를 직접 사용하는 방식입니다.

예를 들어, /data 디렉토리를 PV로 정의할 수 있어요!


장점

  • 별도의 서버 구축 없이 바로 사용 가능합니다.
  • 로컬 디스크의 빠른 성능 활용이 가능해요!

단점

  • 파드가 특정 노드에 고정되어야 하므로 유연성이 떨어져요.
  • 노드 장애 시 데이터 접근이 불가능해지므로 서비스 장애로 이어지겠죠?

분산 스토리지 (Ceph, GlusterFS 등)

분산 스토리지는?:

여러 노드에 데이터를 복제하고 관리하는 스토리지 시스템입니다.


장점

  • 고가용성과 데이터 복제를 제공합니다.
  • 노드 장애에도 데이터가 유지됩니다.

단점

  • 구축과 관리가 복잡해요
  • 홈서버의 제한된 리소스에서는 부담스러울 수 있어요.

NFS

NFS란?: 네트워크를 통해 파일 시스템을 공유하는 프로토콜입니다.

홈서버에 NFS 서버를 구축하면, 쿠버네티스 노드들이 NFS 서버의 디렉토리를 마운트하여 데이터를 저장할 수 있습니다.


장점

  • 초기 비용이 적고, 홈서버 환경에서 손쉽게 구축이 가능하며, 개인 네트워크 내에서 운영할 수 있어요.
  • 여러 Pod가 동시에 접근할 수 있는 공유 스토리지로도 활용이 가능하죠!

단점

  • 단일 장애 지점(SPOF, Single Point of Failure)이 될 수 있으므로, 백업 전략이나 이중화 구성이 필요할 수도 있어요.
  • 관리와 유지보수에 대한 추가 작업이 당연히 요구되겠죠?

그렇다면 홈서버에서 최선의 선택은?

100명 정도의 트래픽을 처리하는 홈서버라고 가정했을 때,

NFS 서버를 따로 구축 하는 것이 가장 현실적이고 효율적인 선택이라고 봐요.

그렇게 생각한 이유는 다음과 같아요!


  • 비용 효율: 외부 클라우드 스토리지 없이 홈서버의 기존 디스크 활용이 가능해요.
  • 확장성: 다중 노드 클러스터에서도 여러 파드가 동일한 스토리지에 접근이 가능하죠!
  • 구축 용이: NFS는 설정이 비교적 매우 간단해요!

근데 만약 단일 노드 클러스터라면 로컬 스토리지 를 사용하는 것도 좋은 방법 중 하나라고 생각해요.

다만 노드 장애 시 그에 따른 백업 전략을 마련해야겠죠?


PV와 PVC 사용 방법

이제 PV와 PVC를 실제로 어떻게 정의하고 사용하는지 예제를 통해 알아볼게요.

NFS를 기반으로 한 설정으로 가정하고 진행하겠습니다~


PV 명세서

apiVersion: v1
kind: PersistentVolume
metadata:
  name: db-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: manual
  nfs:
    path: /mnt/db-data
    server: 192.168.1.100  # 홈서버의 NFS 서버 IP

설명

  • capacity.storage: 스토리지 크기를 10Gi로 설정합니다.
  • accessModes: ReadWriteOnce는 한 노드에서 읽기/쓰기가 가능함을 뜻합니다.
  • persistentVolumeReclaimPolicy: Retain은 PVC가 삭제되어도 데이터를 유지합니다.
  • nfs: NFS 서버의 경로와 IP를 지정합니다.

PVC 명세서

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: db-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: manual

설명

  • PV와 동일한 액세스 모드와 크기를 요청합니다.
  • storageClassName을 통해 수동으로 생성된 PV와 매핑합니다.

Pod 명세서

이제 생성한 PVC를 파드에서 요청해봐야겠죠?

간단하게 mysql 이미지 기반의 데이터베이스 명세서를 작성해볼게요!

apiVersion: v1
kind: Pod
metadata:
  name: db-pod
spec:
  containers:
  - name: database
    image: mysql:latest
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "password"
    volumeMounts:
    - mountPath: /var/lib/mysql
      name: db-storage
  volumes:
  - name: db-storage
    persistentVolumeClaim:
      claimName: db-pvc

설명

  • volumes: PVC를 참조하여 볼륨을 정의합니다.
  • volumeMounts: MySQL 데이터 디렉토리(/var/lib/mysql)에 PVC를 마운트합니다.

Loading script...